<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2020/6/22
 * Time: 17:16
 */


class Encryption{
    public $path;  //文件，或目录

    public $file_path; //目录
    public $new_path;
    public function __construct($path,$new_path=null)
    {
        if(empty($path) || !file_exists($path)){
            exit("文件，路径不存在");
        }
        $this->path = $path;
        $this->file_path = $path;
        if(!is_dir($path)){  //如果不是目录，获取对应目录
            $new_path = dirname($path).'_jm';  //加密目录
            $this->file_path = dirname($path);
        }
        if(empty($new_path)){
            $new_path = $path.'_jm';
        }
        if(!file_exists($new_path)){
            mkdir($new_path,0755,true);
        }
        $this->new_path = $new_path;
    }

    public function encode(){
        list($paths, $files) = $this->_getPathsAndFiles($this->path);
        $this->_createPaths($paths);
        $this->_encryptFiles($files);
    }

    //加密文件
    private function _encryptFiles($files){

        foreach($files as $file){
            $this->_encryptFile($file);
        }
    }



    private function _encryptFile($filename){
        $file = $this->file_path.'/'.$filename;
        $vstr = file_get_contents($file);//要加密的文件
        $v1 = base64_encode($vstr);
        $T_k1 = RandAbc();//随机密匙1    52位
        $T_k2 = RandAbc();//随机密匙2    52位
        //准备混淆
        $strtr_code = strtr($v1, $T_k1, $T_k2); //根据密匙替换对应字符
        $encryption_code_str = $T_k1 . $T_k2 . $strtr_code; //秘钥1（52位）+秘钥2（52位） + 替换好的代码


//定义了5个变量
//下面5个变量最好通过 一个base_decode选择相应字符串拼接上去的，这样代码会乱一点
        $base = "O0O000";
        $strtr = "O0OO00";
        $substr = "OO0O00";
        $number_52 = "OO0000";
        $base64_decode = "O00OO0";
        $c = $urldecode = 'O00OO000';
//$base = 'base';   //$k{0}.$k{1}.$k{2}.$k{3}这样的形式拼接上来 下面的参数也是一样的
//$strtr = 'strtr';
//$substr = 'substr';
//$number_52 = '52';  //这个就是随机秘钥字符的长度
//$base64_decode = 'base64_decode';
        $var_str_bak = <<<'str'
$urldecode_bak = urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A");
$base_bak = $urldecode_bak{3} . $urldecode_bak{6} . $urldecode_bak{33} . $urldecode_bak{30};
$strtr_bak = $urldecode_bak{33} . $urldecode_bak{10} . $urldecode_bak{24} . $urldecode_bak{10} . $urldecode_bak{24};
$substr_bak = $strtr_bak{0} . $urldecode_bak{18} . $urldecode_bak{3} . $strtr_bak{0} . $strtr_bak{1} . $urldecode_bak{24};
$number_52_bak = $urldecode_bak{7} . $urldecode_bak{13}; 
$base64_decode_bak = $base_bak . $urldecode_bak{22} . $urldecode_bak{36} . $urldecode_bak{29} . $urldecode_bak{26} . $urldecode_bak{30} . $urldecode_bak{32} . $urldecode_bak{35} . $urldecode_bak{26} . $urldecode_bak{30};

str;

        //适应 php7.3以及以上版本
        $var_str = <<<'str'
$urldecode_bak = urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A");
$base_bak = $urldecode_bak[3] . $urldecode_bak[6] . $urldecode_bak[33] . $urldecode_bak[30];
$strtr_bak = $urldecode_bak[33] . $urldecode_bak[10] . $urldecode_bak[24] . $urldecode_bak[10] . $urldecode_bak[24];
$substr_bak = $strtr_bak[0] . $urldecode_bak[18] . $urldecode_bak[3] . $strtr_bak[0] . $strtr_bak[1] . $urldecode_bak[24];
$number_52_bak = $urldecode_bak[7] . $urldecode_bak[13]; 
$base64_decode_bak = $base_bak . $urldecode_bak[22] . $urldecode_bak[36] . $urldecode_bak[29] . $urldecode_bak[26] . $urldecode_bak[30] . $urldecode_bak[32] . $urldecode_bak[35] . $urldecode_bak[26] . $urldecode_bak[30];

str;


        $var_str = str_replace('$urldecode_bak', '$' . $urldecode, $var_str);
        $var_str = str_replace('$base_bak', '$' . $base, $var_str);
        $var_str = str_replace('$strtr_bak', '$' . $strtr, $var_str);
        $var_str = str_replace('$substr_bak', '$' . $substr, $var_str);
        $var_str = str_replace('$number_52_bak', '$' . $number_52, $var_str);
        $var_str = str_replace('$base64_decode_bak', '$' . $base64_decode, $var_str);


        $s = $var_str .
            'eval(
        $' . $base64_decode . '("'
            . base64_encode(
                '$' . $c . '="' . $encryption_code_str . '";
                eval(\'?>\'.$' .
                $base64_decode . '(
                        $' . $strtr . '(
                            $' . $substr . '($' . $c . ',$' . $number_52 . '*2),
                            $' . $substr . '($' . $c . ',$' . $number_52 . ',$' . $number_52 . '),
                            $' . $substr . '($' . $c . ',0,$' . $number_52 . ')
                    )
                )
            );') .
            '")
);';

        $s = '<?php
' . $s .
            '
?>';
        //生成 加密后的PHP文件
        $new_file = $this->new_path."/".$filename;
        $a = pathinfo($new_file);
        if(!file_exists($a['dirname'])){
            mkdir($a['dirname'],0777,true);
        }

        if(!file_exists($new_file)){
            $res = touch($new_file);
        }


        $fpp1 = fopen($new_file, 'w');
        if(empty($fpp1)){
            die($new_file."文件打开失败");
        }
        $res = fwrite($fpp1, $s) or die('写文件错误');
        if(empty($res)){
            die($new_file."文件写入失败");
        }

        fclose($fpp1);
        echo $file.":加密完成！<p />";
    }

    //解析文件路径的路径，与文件
    private function _getPathsAndFiles($dir){
        $files = $paths = array();
        if(is_dir($dir)){
            $_files = scandir($dir);
            foreach($_files as $key => $file){
                if($file == '.' || $file == '..'){
                    continue;
                }
                if(is_dir($dir ."/". $file)){
                    $paths[]  = $file;
                    list($subPaths, $subFiles) = $this->_getPathsAndFiles($dir ."/". $file);
                    $subPaths = $this->_addBasePath($subPaths, $file);
                    $subFiles = $this->_addBasePath($subFiles, $file);
                    $paths = array_merge($paths, $subPaths);
                    $files = array_merge($files, $subFiles);
                }
                else{
                    $file_data = pathinfo($file);
                    if (!isset($file_data['extension']) || $file_data['extension'] != 'php') {
                        continue;
                    }
                    $files[] = $file;
                }
            }
        }
        elseif(is_file($dir)){
            $files[] = basename($dir);
        }
        return array($paths, $files);
    }

    private function _addBasePath($files, $base){
        foreach($files as $key => $file){
            $files[$key] = $base . "/" . $file;
        }
        return $files;
    }

    private function _createPaths($paths){
        foreach($paths as $path){
            if(!file_exists($this->new_path . "/" . $path)){
                mkdir($this->new_path . "/" . $path, 0755,true);
            }
        }
    }

    //加密解密原理
    function RandAbc($length = "")
    {//返回随机字符串
        $str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        return str_shuffle($str);
    }


}














